package ca.uwindsor.cs.deepweb.utility;

import java.util.HashSet;
import java.util.Set;

import org.apache.lucene.analysis.Analyzer;
import org.apache.lucene.analysis.standard.StandardAnalyzer;
import org.apache.lucene.document.Document;
import org.apache.lucene.index.IndexWriter;
import org.apache.lucene.search.Hits;

/**
 * Build temporary index using all previous query results, after add the result
 * of last query to this indexer.
 * 
 * @author Liang Jie
 * 
 */
public class IncrementalIndexer {

	private Set<String> set_documents;

	private String string_temp_index_path;

	private Analyzer luceneAnalyzer;

	private String string_uniqueField;

	/**
	 * Build temporary index using all previous query results, after add the
	 * result of last query to this indexer.
	 * 
	 * @param tempindexpath
	 *            The directory to restore the temporary index
	 * @param unique
	 *            The name of a Field in a Lucene Document that uniquely
	 *            identify the document
	 * @throws Exception
	 *             Exceptions when creating index
	 */
	public IncrementalIndexer(String tempindexpath, String unique)
			throws Exception {
		// TODO Auto-generated constructor stub
		set_documents = new HashSet<String>();
		string_temp_index_path = tempindexpath;
		string_uniqueField = unique;
		luceneAnalyzer = new StandardAnalyzer();
		IndexWriter indexWriter = new IndexWriter(string_temp_index_path,
				luceneAnalyzer, true);
		indexWriter.close();
	}

	/**
	 * Add a query result to the IncrementalIndexer, it will build a new index
	 * for next query. After using this method, a new index is built in
	 * specified directory. Then new query could run from the new index built.
	 * 
	 * @param doc
	 *            A Document that is about to add
	 * @throws Exception
	 *             Exceptions when reading last index
	 */
	public void addResult(Document doc) throws Exception {
		IndexWriter indexWriter = new IndexWriter(string_temp_index_path,
				luceneAnalyzer, false);
		if (!set_documents.contains(doc.get(string_uniqueField))) {
			set_documents.add(doc.get(string_uniqueField));
			indexWriter.addDocument(doc);
		}
		indexWriter.close();
	}

	/**
	 * Add a query result to the IncrementalIndexer, it will build a new index
	 * for next query. After using this method, a new index is built in
	 * specified directory. Then new query could run from the new index built.
	 * Caution: Please do not close IndexSearcher before invoke this method
	 * 
	 * @param hits
	 *            The result of last query
	 * @throws Exception
	 *             Exceptions when reading last index
	 */
	public void addResult(Hits hits) throws Exception {
		IndexWriter indexWriter = new IndexWriter(string_temp_index_path,
				luceneAnalyzer, false);
		for (int i = 0; i < hits.length(); i++) {
			if (!set_documents.contains(hits.doc(i).get(string_uniqueField))) {
				set_documents.add(hits.doc(i).get(string_uniqueField));
				indexWriter.addDocument(hits.doc(i));
			}
		}
		indexWriter.close();
	}

//	/**
//	 * Example of using this class.
//	 * 
//	 * @param args
//	 */
//	public static void main(String[] args) {
//
//		Document doc1 = new Document();
//		doc1.add(new Field("ID", "1", Field.Store.YES,
//				Field.Index.UN_TOKENIZED));
//		doc1.add(new Field("name", "Test", Field.Store.YES,
//				Field.Index.TOKENIZED));
//		
//		Document doc2 = new Document();
//		doc2.add(new Field("ID", "2", Field.Store.YES,
//				Field.Index.UN_TOKENIZED));
//		doc2.add(new Field("name", "Test", Field.Store.YES,
//				Field.Index.TOKENIZED));
//		
//		try {
//			IncrementalIndexer index = new IncrementalIndexer("Experiment\\", "ID");
//			index.addResult(doc1);
//			index.addResult(doc2);
//
//			org.apache.lucene.search.IndexSearcher searcher = new IndexSearcher(
//					"Experiment\\");
//			Hits hits = null;
//			Query query = null;
//			QueryParser qp = new QueryParser("name", new StandardAnalyzer());
//
//			query = qp.parse("test");
//			hits = searcher.search(query);
//
//			index.addResult(hits);
//			searcher.close();// important! close the sercher after execute addResult method
//
//			searcher = new IndexSearcher("Experiment\\");
//			qp = new QueryParser("name", new StandardAnalyzer());
//
//			query = qp.parse("test");
//			hits = searcher.search(query);
//			for (int i = 0; i < hits.length(); i++) {
//				System.out.println(hits.doc(i).get("name") + "; Score: "
//						+ hits.score(i));
//			}
//			searcher.close();
//		} catch (Exception e) {
//			// TODO Auto-generated catch block
//			e.printStackTrace();
//		}
//
//	}
}
